"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
exports.__esModule = true;
// 1.
// 告诉ts确实有个$的变量
// declare let $: any;
// 2.
// 静态属性static
var something = /** @class */ (function () {
    function something() {
        something.instances++;
    }
    something.instances = 0;
    return something;
}());
var s1 = new something();
var s2 = new something();
// console.log(something.instances);
// 3.
/**
 * 访问修饰符
 * public：类、子类、实例都可访问，默认值。
 * protected：类、子类能，实例不能
 * private：类能、子类、实例不能
 */
// 4.
/**
 * 抽象类abstract
 * 可以作用在类及类的任何成员上。
 * 拥有abstract修饰符意味着该函数不能直接被调用，不能被实例化，要被继承，并且子类必须实现这个功能
 */
// 5.
// 普遍的写法
// class Foo {
//     x: number
//     constructor(x:number) {
//         this.x = x
//     }
// }
// 简写,会在类上自动声明，并且从构造器中复制过去
var Foo = /** @class */ (function () {
    function Foo(x) {
        this.x = x;
    }
    return Foo;
}());
// 6.
/**
 * 基本语法
 */
// 原始类型
var num, str, bool;
// 数组
var boolArr;
boolArr = [true, false];
var name = {
    first: "z",
    second: "zd"
};
// 特殊类型 any、null、undefined、void
// any、null和undefined可以被赋值给所有类型，要开启strictNullChecks选项
var a;
a = null;
a = undefined;
function log() { }
// 泛型: 对参数和返回值的约束
function reverse(items) {
    var toreturn = [];
    for (var i = items.length - 1; i >= 0; i--) {
        toreturn.push(items[i]);
    }
    return toreturn;
}
var reversed = reverse([1, 2, 3]);
// console.log(reversed);
// 联合类型
function formatCommandline(command) {
    var line = "";
    if (typeof command === "string") {
        line = command.trim();
    }
    else {
        line = command.join(" ").trim();
    }
}
// 交叉类型
// T、U继承自对象，返回值有T和U的全部属性
function extend(first, second) {
    var res = {};
    for (var id in first) {
        res[id] = first[id];
    }
    for (var id in second) {
        if (!res.hasOwnProperty(id)) {
            res[id] = second[id];
        }
    }
    return res;
}
var x = extend({ a: "hello" }, { b: 42 });
// console.log(x);
// 元组类型
var nameNumber = ["1", 2];
var name2 = nameNumber[0], num2 = nameNumber[1];
var MyPoint = /** @class */ (function () {
    function MyPoint() {
    }
    return MyPoint;
}());
/**
 * 枚举
 */
var CardSuit;
(function (CardSuit) {
    CardSuit[CardSuit["Clubs"] = 0] = "Clubs";
    CardSuit[CardSuit["Diamonds"] = 1] = "Diamonds";
    CardSuit[CardSuit["Hearts"] = 2] = "Hearts";
    CardSuit[CardSuit["Spaders"] = 3] = "Spaders";
})(CardSuit || (CardSuit = {}));
// console.log(CardSuit.Clubs); // 0
var strEnum;
(function (strEnum) {
    strEnum["a"] = "1";
    strEnum["b"] = "2";
})(strEnum || (strEnum = {}));
function stringOrNumber(foo) {
    if (typeof foo === "number") {
        return foo * foo;
    }
    else if (typeof foo === "string") {
        return "hello ".concat(foo);
    }
}
var overloaded = stringOrNumber;
// 使用
var str2 = overloaded(""); // str 被推断为 'string'
var num3 = overloaded(123); // num 被推断为 'number'
var foo = {};
foo.bar = 123;
foo.bas = "hello";
// 双重断言
//   function handler(event: Event) {
//     const element = event as HTMLElement; // Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个
//   }
function handler(event) {
    var element = event; // ok
}
// 泛型  常用T、U、V表示
var Queue = /** @class */ (function () {
    function Queue() {
        var _this = this;
        this.data = [];
        this.push = function (item) { return _this.data.push(item); };
        this.pop = function () { return _this.data.shift(); };
    }
    return Queue;
}());
var queue = new Queue();
var point2D = { x: 0, y: 10 };
var point3D = { x: 0, y: 10, z: 20 };
function iTakePoint2D(point) {
    /* do something */
    console.log(point);
}
iTakePoint2D(point2D); // ok, 完全匹配
iTakePoint2D(point3D); // 额外的信息，没关系    类型是结构化的
var iTakeSomethingAndPassItAnErr = function (x) {
    /* 做一些其他的 */
};
iTakeSomethingAndPassItAnErr(function () { return null; }); // ok
iTakeSomethingAndPassItAnErr(function (err) { return null; }); // ok
iTakeSomethingAndPassItAnErr(function (err, data) { return null; }); // ok
var value;
value = 1;
value = 's';
/**
 * 泛型
 */
function pickObjectKeys(obj, keys) {
    var res = {};
    for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
        var key = keys_1[_i];
        if (key in obj) {
            res[key] = obj[key];
        }
    }
    return res;
}
var language = {
    name: 'ts',
    age: 8,
    extensions: ['ts', 'tsx']
};
var ageExtensions = pickObjectKeys2(language, ['age', 'extensions']);
// console.log(ageExtensions);
function pickObjectKeys2(obj, keys) {
    var res = {};
    for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
        var key = keys_2[_i];
        if (key in obj) {
            res[key] = obj[key];
        }
    }
    return res;
}
function identity(value) {
    return value;
}
var res = identity(123);
var res2 = identity({ name: 'ts' });
// const data = await fetchApi('./users')
// console.log(data.a);
function stringObjectKeyValues(obj) {
    return Object.keys(obj).reduce(function (acc, key) {
        var _a;
        return (__assign(__assign({}, acc), (_a = {}, _a[key] = JSON.stringify(obj[key]), _a)));
    }, {});
}
var stringfiedValues = stringObjectKeyValues({ a: '1', b: 2, c: true, d: [1, 2, 3] });
console.log(stringfiedValues);
